package com.rw.engine.asynchronous.aspect;

import com.rw.engine.asynchronous.anno.AsyncMethod;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;

import javax.annotation.Resource;
import java.lang.reflect.Method;

/**
 * 异步调用切片
 */
@Aspect
public class AsyncAspect {
    /**
     * Spring容器
     * 我们的过滤规则需要从Spring容器里面拿取
     * 以确保用户可以自定义过滤规则
     */
    @Resource
    protected ApplicationContext applicationContext;

    @Around("@annotation(com.rw.engine.asynchronous.anno.AsyncMethod)")
    public Object signCheck(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取方法的对象
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();

        // 获取所有传入的参数
        Object[] args = joinPoint.getArgs();

        // 获取方法上的注解
        AsyncMethod async = method.getAnnotation(AsyncMethod.class);

        findFilterRule(async.asyncDeliver()).deliver(joinPoint.getTarget(), method, args, async);
        return null;
    }

    /**
     * 尝试从Spring容器里取出过滤规则
     * 如果取出失败，则构建一个对象
     *
     * @return 取出或构建的对象
     */
    private <CustomFilterRule> CustomFilterRule findFilterRule(Class<CustomFilterRule> filterRuleClass)
            throws InstantiationException, IllegalAccessException {
        try {
            return applicationContext.getBean(filterRuleClass);
        } catch (BeansException exception) {
            return filterRuleClass.newInstance();
        }
    }
}
